package com.hdl.factory;

import com.hdl.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.SQLException;

/**
 * @author hedonglin
 * @date 2020/5/3 13:15
 * @description 代理工厂
 */
@Component
public class ProxyFactory {
    @Autowired
    private TransactionManager transactionManager;

    /**
     * Jdk动态代理
     * @param obj  委托对象
     * @return   代理对象
     */
    public Object getJdkProxy(Object obj) {
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), (proxy, method, args) -> getResult(obj, method, args));
    }


    /**
     * cglib动态代理
     * @param obj  委托对象
     * @return   代理对象
     */
    public Object getCglibProxy(Object obj) {
        return Enhancer.create(obj.getClass(),
                (MethodInterceptor) (o, method, objects, methodProxy) -> getResult(obj, method, objects));
    }

    /**
     * 获取返回结果
     */
    private Object getResult(Object proxyObj, Method method, Object[] args) throws Exception {
        Object result = null;
        try {
            // 开启事务(关闭事务的自动提交)
            transactionManager.beginTransaction();

            result = method.invoke(proxyObj, args);

            // 提交事务
            transactionManager.commit();
            return result;
        } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
            // 回滚事务
            transactionManager.rollback();
            throw e;
        }
    }
}
